#include "gkt_board.h"
#include "gkt_debug.h"
#include "gkt_driver.h"
#include "gkt_rtc.h"
#include "gkt_flash_partition.h"
#include "gkt_user.h"
#include "gkt_record_unlock.h"
#include "gkt_door.h"
#include "window_common.h"
#include "gkt_os.h"
#include "gkt_bg_job.h"
#include "gkt_fpsensor.h"
#include "gkt_gpio.h"
#include "gkt_rfid.h"
#include "gkt_backboard.h"
#include "gkt_wdt.h"
#include "gkt_adc.h"
#include "gkt_battery.h"
#include "gkt_lighting_effect.h"
#include "gkt_version.h"
#include "gkt_wakeup.h"
#if	defined(GKT_CONFIG_PROXIMITY_SENSOR_ENABLE)&&(GKT_CONFIG_PROXIMITY_SENSOR_ENABLE)
#include "gkt_pr_sensor.h"
#endif
#include "gkt_card.h"

#if defined(GKT_CONFIG_RTC_DISABLE) && GKT_CONFIG_RTC_DISABLE
#define check_or_set_default_date_time()	do {} while(0)
#else
static void check_or_set_default_date_time(void)
{
	gkt_date_time_s dt;
	int retval;

	retval = gkt_rtc_get_time(&dt);
	if (GKT_SUCCESS == retval) {
		retval = gkt_dt_check_date(&dt.date);
		if (!retval)
			goto set_default_dt;

		retval = gkt_dt_check_time(&dt.time);
		if (!retval)
			goto set_default_dt;

		return;
	}
	else if (GKT_EAGAIN == retval)
		return;

set_default_dt:
	dt.date.year = GKT_WINDOW_DATE_YEAR_DEFAULT;
	dt.date.month = GKT_DT_MONTH_JAN;
	dt.date.day = 1;
	dt.time.hour = 0;
	dt.time.minute = 0;
	dt.time.second = 0;
	gkt_rtc_set_time(&dt);
}
#endif

#if defined(GKT_CONFIG_SCREEN_ENABLE) && GKT_CONFIG_SCREEN_ENABLE
#if defined(GKT_CONFIG_WINDOW_TEXT_CHINESE_ENABLE) && GKT_CONFIG_WINDOW_TEXT_CHINESE_ENABLE
static const uint8_t sc_boot_image_data[] = {
	0x00,0x10,0x90,0x10,0x10,0x10,0x10,0x10,0x10,0xD0,0xF8,0x10,0x00,0x00,0x00,0xF0,
	0xBE,0x84,0x80,0x80,0x80,0x80,0x80,0x80,0xC0,0x80,0x00,0x00,0x00,0x00,0x00,0x00,
	0x04,0x38,0x70,0x00,0x00,0x00,0xF8,0xF0,0x10,0x08,0x08,0x04,0x06,0xE4,0xE0,0x20,
	0x20,0x20,0x20,0xE0,0xE0,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x08,0x08,0x08,
	0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0xFC,
	0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xE0,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
	0x22,0x2C,0x3C,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xE0,0x70,0x20,0x00,0x00,
	0x00,0x00,0x00,0x01,0x02,0x0C,0x98,0xF0,0xFC,0x87,0x00,0x00,0x30,0x08,0x07,0x01,
	0x00,0xF8,0x3E,0xF0,0x00,0x00,0x0C,0x02,0x01,0x01,0x00,0x00,0x00,0x04,0x04,0x04,
	0x04,0xFC,0xFC,0x04,0x00,0x00,0xFF,0xFF,0x00,0x80,0x80,0x40,0x40,0xFF,0xFF,0x00,
	0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,
	0x00,0xFE,0xFE,0x82,0x82,0x82,0x82,0x82,0x82,0xFE,0xFE,0x02,0x00,0x00,0x00,0xFF,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x81,0x80,0x80,0x42,0x42,0x22,0x32,0x1A,0x8E,
	0xD6,0x62,0xC2,0x82,0x82,0x42,0xC2,0x22,0x33,0x12,0x01,0x00,0x00,0x00,0x00,0x00,
	0x00,0x40,0x20,0x10,0x0C,0x06,0x01,0x00,0x00,0x03,0x1F,0x1C,0x80,0x40,0x20,0x18,
	0x0F,0x03,0x00,0x01,0x0E,0x38,0x60,0xC0,0x80,0x00,0x00,0x00,0x00,0x40,0xE0,0x60,
	0x30,0x1F,0x1F,0x10,0x20,0x40,0xC3,0x87,0x81,0x81,0x80,0x80,0x80,0xFF,0xBF,0x80,
	0x80,0x82,0x82,0x87,0x83,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x40,0x40,0x40,
	0x40,0x43,0x43,0x40,0x40,0x40,0x40,0x40,0x40,0x43,0x41,0x40,0x40,0x40,0x40,0xFF,
	0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x10,0x10,0x08,0x88,0x84,0x46,0x62,0x21,0x11,
	0x18,0x0C,0x06,0xFF,0xFE,0x00,0x03,0x0C,0x18,0x30,0x60,0xC0,0xC0,0x40,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x02,0x01,0x01,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x01,
	0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
	0x00,0x00,0x00,0x00,0x00,0x02,0x02,0x01,0x01,0x01,0x00,0x00,0x00,0x00,0x01,0x01,
	0x02,0x06,0x07,0x03,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
};
#define BOOT_IMAGE_WIDTH	112
#define BOOT_IMAGE_HEIGHT	28
#else/***********english boot image***************/
static const uint8_t sc_boot_image_data[] = {
0x00,0x20,0xe0,0xe0,0x20,0x00,0x20,0xe0,0xe0,0x20,0x00,0x00,0x20,0xe0,0x20,0x20,
0x20,0xe0,0xe0,0x20,0x20,0x20,0x20,0x20,0x20,0x60,0xe0,0x80,0x00,0x00,0x20,0x20,
0xe0,0xe0,0x20,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xc0,
0x60,0x20,0x20,0x20,0x20,0x40,0xc0,0x80,0x00,0x00,0x00,0x00,0x80,0x40,0x20,0x20,
0x20,0x20,0x40,0x80,0x00,0x00,0x00,0x00,0x20,0xe0,0xe0,0x00,0x00,0x00,0x00,0x00,
0xc0,0xe0,0xe0,0x20,0x00,0x20,0x20,0xe0,0xe0,0x20,0x20,0x20,0x20,0x20,0x20,0x60,
0xe0,0x80,0x00,0x00,0x00,0x00,0x01,0xff,0xf0,0x00,0x80,0x7c,0x7f,0xf8,0x00,0xc0,
0x3f,0x00,0x00,0x00,0x00,0xff,0xff,0x20,0x20,0x20,0x20,0x70,0xfc,0x00,0x00,0x01,
0x00,0x00,0x00,0x00,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0xf8,0xff,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0xfc,0xff,
0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0xff,0xfc,0x00,0x00,0x00,0xff,0x07,0xff,
0xe0,0x00,0x80,0x78,0x07,0xff,0xff,0x00,0x00,0x00,0x00,0xff,0xff,0x20,0x20,0x20,
0x20,0x70,0xfc,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x3f,0xf8,0x07,0x00,
0x00,0x1f,0xfc,0x07,0x00,0x00,0x00,0x80,0x80,0xff,0xff,0x80,0x80,0x80,0x80,0x80,
0x81,0xc0,0xe0,0x18,0x00,0x00,0x80,0x80,0xff,0xff,0x80,0x80,0x80,0x80,0x80,0xc0,
0xe0,0x38,0x00,0x00,0x07,0x1f,0x78,0x60,0xc0,0x80,0x80,0x80,0x80,0x40,0x20,0x18,
0x00,0x00,0x07,0x1f,0x38,0x40,0x80,0x80,0x80,0x80,0x40,0x30,0x1f,0x07,0x00,0x00,
0x80,0xff,0x80,0x00,0x1f,0xfc,0x0f,0x00,0x80,0xff,0xff,0x80,0x00,0x80,0x80,0xff,
0xff,0x80,0x80,0x80,0x80,0x80,0x81,0xc0,0xe0,0x18,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
};
#define BOOT_IMAGE_WIDTH	100
#define BOOT_IMAGE_HEIGHT	28
#endif
static void show_booting_image(void)
{
	gkt_rect_s rect;

	if (g_system_info.reset_mode != GKT_SYSTEM_RESET_WAKEUP) {
		rect.x = (GKT_SCREEN_WIDTH - BOOT_IMAGE_WIDTH) >> 1;
		rect.y = WINDOW_WIDGET_NORMAL_HEIGHT;
		rect.width = BOOT_IMAGE_WIDTH;
		rect.height = BOOT_IMAGE_HEIGHT;

		gkt_screen_control(GKT_SCREEN_CTRL_DISPLAY_CLEAR, 0);
		gkt_screen_draw_bitmap(sc_boot_image_data, 
				&rect, WINDOW_BOOT_IMAGE_FG_COLOR,
				WINDOW_BOOT_IMAGE_BG_COLOR, 1);
	}
}
#else
#define show_booting_image()	do {} while(0)
#endif

#define WINDOW_BG_JOB_SYNC_UNIT	10
#define WINDOW_BG_JOB_SYNC_TIMEOUT	3000

#if defined(GKT_CONFIG_WDTE_ENABLE) && GKT_CONFIG_WDTE_ENABLE
#include "gkt_wdt.h"
#define app_main_wdt_feed()	gkt_wdt_feed()
#else
#define app_main_wdt_feed()	do {} while (0)
#endif

#if	defined(GKT_CONFIG_PROXIMITY_SENSOR_ENABLE) && (GKT_CONFIG_PROXIMITY_SENSOR_ENABLE)
static void pr_sensor_wake_up_handle(void)
{
	gkt_date_time_s dts_current;
	uint32_t wake_up_time, value;	/* default */
	int retval;

	if (GKT_SYSTEM_RESET_WAKEUP != g_system_info.reset_mode) {
		g_window_retmem_data.pr_power_state = GKT_PR_SENSOR_POWER_ON;
		g_window_retmem_data.pr_power_cnt = 0;
		g_window_retmem_data.pr_power_clear_dtu = 0;
		value = 0;
		BPK_WriteKey(&value, 1, GKT_RETMEM_PROXIMITY_POWER_STATE_COUNT);
		BPK_WriteKey(&g_window_retmem_data.pr_power_clear_dtu, 1, GKT_RETMEM_PROXIMITY_POWER_CLEAR_DTU);
		window_pr_sensor_handle();
	}
	else {
		BPK_ReadKey(&value, 1, GKT_RETMEM_PROXIMITY_POWER_STATE_COUNT);
		g_window_retmem_data.pr_power_cnt = (value >> 16) & 0xffff;
		g_window_retmem_data.pr_power_state = value & 0xffff;
		BPK_ReadKey(&g_window_retmem_data.pr_power_clear_dtu, 1, GKT_RETMEM_PROXIMITY_POWER_CLEAR_DTU);
	}
	gkt_trace("main: %d line. pr_sensor_always_enable=%d, pr_power_cnt=%d, \
		pr_sensor_state=%d, pr_power_state=%d\n", __LINE__,
		gp_window_data->pr_sensor_always_enable,
		g_window_retmem_data.pr_power_cnt,
		gp_window_data->pr_sensor_state,
		g_window_retmem_data.pr_power_state);

	if (gp_window_data->pr_sensor_always_enable != 0) {
		g_window_retmem_data.pr_power_cnt = 0;
		g_window_retmem_data.pr_power_clear_dtu = 0;
		BPK_ReadKey(&value, 1, GKT_RETMEM_PROXIMITY_POWER_STATE_COUNT);
		value &= 0xFFFF;
		value |= g_window_retmem_data.pr_power_cnt << 16; 
		BPK_WriteKey(&value, 1, GKT_RETMEM_PROXIMITY_POWER_STATE_COUNT);
		BPK_WriteKey(&g_window_retmem_data.pr_power_clear_dtu, 1, GKT_RETMEM_PROXIMITY_POWER_CLEAR_DTU);
		return;
	}
	if ((GKT_WAKEUP_SRC_none == gkt_wakeup_get_source())
		|| (GKT_WAKEUP_SRC_prsensor == gkt_wakeup_get_source()))
	{
		retval = gkt_rtc_get_time(&dts_current);
		if (GKT_SUCCESS == retval) {
			wake_up_time = GKT_DTS_2_DTU(dts_current);
			if (wake_up_time < g_window_retmem_data.pr_power_clear_dtu) {
				g_window_retmem_data.pr_power_cnt++;
				if (g_window_retmem_data.pr_power_cnt > GKT_PR_SENSOR_POWER_OFF_CNT_MAX) {
					g_window_retmem_data.pr_power_state = GKT_PR_SENSOR_POWER_OFF;
					g_window_retmem_data.pr_power_cnt = 0;
					g_window_retmem_data.pr_power_clear_dtu = 0;
					if (gp_window_data->pr_sensor_state != GKT_PR_SENSOR_SENSE_SHUTDOWN)
						gkt_pr_sensor_set_threshold(GKT_PR_SENSOR_SENSE_SHUTDOWN, 1);
				}
			}
			else {
				g_window_retmem_data.pr_power_cnt = 0;
			}
			gkt_dt_add_seconds(&dts_current, GKT_PR_SENSOR_POWER_OFF_TIME_S);
			g_window_retmem_data.pr_power_clear_dtu = GKT_DTS_2_DTU(dts_current);

			value = g_window_retmem_data.pr_power_cnt << 16;
			value |= g_window_retmem_data.pr_power_state;
			BPK_WriteKey(&value, 1, GKT_RETMEM_PROXIMITY_POWER_STATE_COUNT);
			BPK_WriteKey(&g_window_retmem_data.pr_power_clear_dtu, 1, GKT_RETMEM_PROXIMITY_POWER_CLEAR_DTU);
		}
		else
			gkt_error("pr_sensor_wake_up_handle:get rtc time err=%d\n", retval);
	}
}
#endif
void gkt_app_main(void *params)
{
	int retval;
	uint32_t value;
	
	gkt_trace("app_main: start ...\n");

	gkt_bg_job_init();
	
#ifdef GKT_CONFIG_SCREEN_BACKLIGHT_CTL_GPIO_PIN	
	retval = gkt_gpio_config(GKT_CONFIG_SCREEN_BACKLIGHT_CTL_GPIO_PIN,
					GKT_GPIO_F_OUTPUT, NULL);
	if (retval != GKT_SUCCESS) {
		gkt_error("gkt_app_main: config screen backlight failed %d\n", retval);
	}
	gkt_gpio_set_pin_level(GKT_CONFIG_SCREEN_BACKLIGHT_CTL_GPIO_PIN, 0);
#endif

	show_booting_image();
	check_or_set_default_date_time();

	app_main_wdt_feed();

#if defined(GKT_CONFIG_BACKBOARD_ENABLE) && GKT_CONFIG_BACKBOARD_ENABLE
	retval = gkt_backboard_init();
	if (retval != GKT_SUCCESS) {
		gkt_error("app_main: backboard init failed %d\n", retval);
		return;
	}
#endif

	retval = gkt_flash_partition_init();
	if (retval != GKT_SUCCESS) {
		gkt_error("app_main: flash partition init failed %d\n", retval);
		return;
	}

	/* window data */
	window_data_init();

	G_BPK_ReadKey(&value, 1, GKT_RETMEM_ALWAYS_MODE_STATUS);
	g_window_retmem_data.always_open_enabled = value;
	gkt_window_system_door_set_always_open_state(
			g_window_retmem_data.always_open_enabled);

	if (gp_window_unreset_data->keypad_parameter_value == 0) {
		if (GKT_KEYPAD_PAPAMETERS == GKT_KEYPAD_PAPAMETERS_STANDARD) {
			gkt_printf("key used standard param\n");
			gp_window_unreset_data->keypad_parameter_value = GKT_KEYPAD_RESPONSE_STANDARD;
		}
		else {
			gkt_printf("key used sensitivity param\n");
			gp_window_unreset_data->keypad_parameter_value = GKT_KEYPAD_RESPONSE_SENSITIVITY;
		}
		gkt_key_parameter_update(gp_window_unreset_data->keypad_parameter_value);
	}
	else {
		if (gp_window_unreset_data->keypad_parameter_value == GKT_KEYPAD_RESPONSE_SENSITIVITY)
			gkt_printf("key used sensitivity param\n");
		else
			gkt_printf("key used standard param\n");
		gkt_key_parameter_update(gp_window_unreset_data->keypad_parameter_value);
	}

	/* led */
	gkt_led_init();
	gkt_ambient_light_init();

	/* user manager init */
	gkt_user_init();
#if	defined(GKT_CONFIG_PROXIMITY_SENSOR_ENABLE) && (GKT_CONFIG_PROXIMITY_SENSOR_ENABLE)
	pr_sensor_wake_up_handle();
#endif
	/* unlock record model init */
	gkt_record_unlock_init();

#if defined(GKT_CONFIG_MULTIPLE_LANGUAGE_SUPPORT) && GKT_CONFIG_MULTIPLE_LANGUAGE_SUPPORT
	/* init language */
	gkt_language_config(gp_window_data->language);
#endif

#if defined(GKT_CONFIG_RFID_ENABLE) && GKT_CONFIG_RFID_ENABLE	\
	&& defined (GKT_CONFIG_RFID_YC5018) && GKT_CONFIG_RFID_YC5018
	if (gp_window_unreset_data->yc_rfid_gain != 0)
		gkt_rfid_factory_gain_set(gp_window_unreset_data->yc_rfid_gain);
	if (gp_window_unreset_data->yc_rfid_water_level_factory != 0) 
		gkt_rfid_factory_water_level_set(gp_window_unreset_data->yc_rfid_water_level_factory);
#endif

	/* init window manager */
	retval = gkt_window_manager_init();
	if (retval != GKT_SUCCESS) {
		gkt_error("app_main: window manager init failed!\n");
		return;
	}

	/* init window key */
	window_key_init();

	/* init window text table */
	window_text_init();

	/* init image table */
	window_image_init();

	/* init voice */
#if !GKT_VOICE_OUTPUT_VOLUME_DISABLE
	if (gp_window_data->voice_volume >= GKT_VOICE_OUTPUT_VOLUME_MAX)
		gp_window_data->voice_volume = GKT_VOICE_OUTPUT_VOLUME_DEFAULT;
	gkt_voice_output_set_volume(gp_window_data->voice_volume);
#endif
	window_voice_combined_init();

	/* door lock */
#if defined(GKT_CONFIG_DOOR_TAMPER_ENABLE) && GKT_CONFIG_DOOR_TAMPER_ENABLE
		if (!gp_window_data->door_tamper_alarm_enable) {
			gkt_gpio_interrupt_clear(GKT_CONFIG_DOOR_TAMPER0_GPIO_PIN);
#if defined(GKT_CONFIG_DOOR_TAMPER1_GPIO_PIN)
			gkt_gpio_interrupt_clear(GKT_CONFIG_DOOR_TAMPER1_GPIO_PIN);
#endif			
		}
			//gkt_wkio_clear(GKT_CONFIG_DOOR_TAMPER_WKIO_PIN);
#endif
#if defined(GKT_CONFIG_DOOR_LOCK_ENABLE) && GKT_CONFIG_DOOR_LOCK_ENABLE			
#if !GKT_DOOR_LOCK_MOTOR_ROTATE_DIRECTION_FIXED
		gkt_door_lock_set_motor_rotate_direction(
			gp_window_unreset_data->lock_motor_rotate_direction);
#endif
#endif		
#if !GKT_DOOR_LOCK_MOTOR_ROTATE_TIME_FIXED
		gkt_door_lock_set_motor_rotate_time(GKT_DOOR_LOCK_MOTOR_ROTATE_TIME_CLOSE,
			gp_window_unreset_data->lock_motor_rotate_time_ms);
#endif
#if defined(GKT_CONFIG_DOOR_LOCK_AUTOMATIC) && GKT_CONFIG_DOOR_LOCK_AUTOMATIC
		gkt_door_lock_set_motor_rotate_time(GKT_DOOR_LOCK_MOTOR_ROTATE_TIME_FULL,
			gp_window_unreset_data->lock_motor_full_rotate_time_ms);
		gkt_door_lock_set_motor_rotate_time(GKT_DOOR_LOCK_MOTOR_ROTATE_TIME_DOUBLE_CLOSE,
			gp_window_unreset_data->lock_double_close_motor_rotate_time_ms);
#if (GKT_MODULE_LOC_BACKBOARD == GKT_DOOR_LOCK_LOCATION)
		retval = gkt_door_lock_set_auto_close_time(1, gp_window_data->lock_auto_double_close_time);
		if (GKT_EINPROCESS != retval)
			gkt_error("app_main: gkt_door_lock_set_auto_close_time failed!\n");
#endif
#if (GKT_MODULE_LOC_FRONTBOARD == GKT_DOOR_LOCK_LOCATION)
			gkt_door_lock_set_motor_locked_rotor_voltage(
				gp_window_unreset_data->lock_motor_locked_rotor_voltage);
#endif
#endif

	/* save data if need */
	window_data_save();
	
	if (g_system_info.reset_mode != GKT_SYSTEM_RESET_WAKEUP) {
		int sync_complete, timeout_left;

#if !defined(GKT_CONFIG_DOOR_LOCK_AUTOMATIC) \
	|| !GKT_CONFIG_DOOR_LOCK_AUTOMATIC
		uint32_t lock_status = gkt_door_lock_get_status();
		if (lock_status != GKT_DOOR_LOCK_ST_CLOSED) {
			gkt_printf("app_main: close lock ...\n");
			gkt_door_lock_close(0);
		}
#endif
#if	defined(GKT_CONFIG_PROXIMITY_SENSOR_ENABLE)	&& (GKT_CONFIG_PROXIMITY_SENSOR_ENABLE)
		gkt_pr_sensor_set_threshold(gp_window_data->pr_sensor_state, 0);
#endif
		gkt_bg_job_enable();
		app_main_wdt_feed();

		timeout_left = WINDOW_BG_JOB_SYNC_TIMEOUT;
		do {
			sync_complete = gkt_bg_job_sync_complete();
			if (sync_complete)
				break;

			gkt_thread_sleep(WINDOW_BG_JOB_SYNC_UNIT);
			timeout_left -= WINDOW_BG_JOB_SYNC_UNIT;
		} while (timeout_left > 0);
		gkt_info("app_main: sync bg_job complete!\n");

		app_main_wdt_feed();
	}
	else
		gkt_bg_job_enable();

	//gkt_driver_clock_aon_32k_measure_control(1, 0);
#if defined(GKT_CONFIG_DOOR_LOCK_AUTOMATIC) && GKT_CONFIG_DOOR_LOCK_AUTOMATIC \
	&& (GKT_MODULE_LOC_FRONTBOARD == GKT_DOOR_LOCK_LOCATION)
	if (GKT_WAKEUP_SRC_none == gkt_wakeup_get_source()) {
		if (gkt_rtc_detect_alarm() == GKT_SUCCESS)
			gkt_wakeup_set_source(GKT_WAKEUP_SRC_RTC);
	}
#endif
	/* start window manager & show welcome window */
	gkt_window_manager_start(WINDOW_ID_welcome);

	GKT_ASSERT(0);
}

void gkt_app_lphook(int when, int mode)
{
	int retval=GKT_SUCCESS;

#if GKT_CONFIG_VOICE_OUTPUT_ENABLE
	gkt_voice_output_stop();
#endif

#if defined(GKT_CONFIG_SLIDING_CLOSURE_MAGNET_LEVEL)
	gkt_sliding_closure_magnet_control(0);
#endif	
	
#if defined(GKT_CONFIG_AMBIENT_LIGHT_ENABLE) && GKT_CONFIG_AMBIENT_LIGHT_ENABLE
	gkt_ambient_light_set_state(GKT_AMBIENT_LIGHT_STATE_OFF, 0, 0);
#endif

#if defined(GKT_CONFIG_SCREEN_ENABLE) && GKT_CONFIG_SCREEN_ENABLE
	gkt_screen_control(GKT_SCREEN_CTRL_POWEROFF, 0);
	//gkt_screen_control(GKT_SCREEN_CTRL_SLEEP, 0);
#endif
	
#if defined(GKT_CONFIG_RFID_ENABLE) && GKT_CONFIG_RFID_ENABLE
	gkt_event_mask_single(GKT_EVENT_CARD, 0);
#endif

#if defined(GKT_CONFIG_KEY_WAKEUP_NO_CALIBRATE) && GKT_CONFIG_KEY_WAKEUP_NO_CALIBRATE
	if (GKT_DRIVER_LP_NORMAL == gkt_driver_get_lp_mode()) {
		gkt_thread_sleep(10);
		gkt_keypad_control(GKT_KEYPAD_CTRL_ENABLE, 0);
		gkt_keypad_update_backup_freq();
	}
#endif

	gkt_key_led_control(GKT_KEY_LED_CTRL_ENABLE, 0);
	gkt_led_standby();
#if defined GKT_CONFIG_AMBIENT_LIGHT_META_2_GPIO_PIN 	
	gkt_ambient_light_standby();
#endif

#if defined(GKT_CONFIG_DOOR_LOCK_ENABLE) && GKT_CONFIG_DOOR_LOCK_ENABLE \
		&& (!defined(GKT_CONFIG_BACKBOARD_ENABLE) || !GKT_CONFIG_BACKBOARD_ENABLE) \
		&& (!defined(GKT_CONFIG_DOOR_LOCK_AUTOMATIC) || !GKT_CONFIG_DOOR_LOCK_AUTOMATIC)
	gkt_door_lock_standby();
#endif

	gkt_adc_standby();
	gkt_lighting_effect_standby();

#if defined(GKT_CONFIG_INTERNAL_DOORBELL_ENABLE) && GKT_CONFIG_INTERNAL_DOORBELL_ENABLE
	gkt_gpio_config(GKT_CONFIG_INTERNAL_DOORBELL_GPIO_PIN, GKT_GPIO_F_OUTPUT, NULL);
	gkt_gpio_set_pin_level(GKT_CONFIG_INTERNAL_DOORBELL_GPIO_PIN, 0);
#endif

	if (GKT_CONFIG_VOICE_OUTPUT_OPAMP_EN_PIN != GKT_CONFIG_DEVICE_POWER_CTRL_PIN) {
		gkt_voice_output_disable_opamp();
		gkt_thread_sleep(20);
	}

#if !defined(GKT_CONFIG_DEVICE_POWER_CTRL_DOWN_DELAYED)	\
	|| !GKT_CONFIG_DEVICE_POWER_CTRL_DOWN_DELAYED
	gkt_driver_device_power_down();
#endif

#ifdef GKT_CONFIG_SCREEN_BACKLIGHT_CTL_GPIO_PIN	
	gkt_gpio_set_pin_level(GKT_CONFIG_SCREEN_BACKLIGHT_CTL_GPIO_PIN, 1);
#endif
#if defined(GKT_CONFIG_SCREEN_ENABLE) && GKT_CONFIG_SCREEN_ENABLE
	gkt_screen_control(GKT_SCREEN_CTRL_SLEEP, 0);
#endif

#if defined(GKT_CONFIG_DAC_OUTPUT_P_PIN)
	gkt_thread_sleep(100);
	retval = gkt_gpio_config(GKT_CONFIG_DAC_OUTPUT_P_PIN, GKT_GPIO_F_OUTPUT, NULL);
	if (retval != GKT_SUCCESS)
		gkt_error("DAC_OUTPUT_P_PAD_PIN config output err=%d\n",retval);
	gkt_gpio_set_pin_level(GKT_CONFIG_DAC_OUTPUT_P_PIN, 0);
#endif

#if defined(GKT_CONFIG_RFID_ENABLE)	\
	&& GKT_CONFIG_RFID_ENABLE	\
	&& defined(GKT_CONFIG_RFID_STANDBY_ENABLE) \
	&& GKT_CONFIG_RFID_STANDBY_ENABLE
#if defined(GKT_CONFIG_RFID_QUERY_MODE_ENABLE) && GKT_CONFIG_RFID_QUERY_MODE_ENABLE 					
	gkt_card_polling_control(0);
#if (defined(GKT_CONFIG_RFID_YC5018_KEYPAD_MUTUAL_EXCLUSION)	\
		&& GKT_CONFIG_RFID_YC5018_KEYPAD_MUTUAL_EXCLUSION)	\
	|| (defined(GKT_CONFIG_RFID_YC5018_PROXIMITY_SENSOR_MUTUAL_EXCLUSION)	\
		&& GKT_CONFIG_RFID_YC5018_PROXIMITY_SENSOR_MUTUAL_EXCLUSION)	
	gkt_rfid_control(GKT_RFID_CTRL_ENABLE, GKT_RFID_EXT_DATA_KEY);
#endif
#endif
	uint8_t rfid_type;
	gkt_user_amount_s amount;
	
	amount.used_nums = 0;
	gkt_user_get_amount(&amount, GKT_USER_AUTH_ADMIN, GKT_USER_TYPE_MAX);
	
	gkt_get_rfid_type(&rfid_type);
#if defined(GKT_CONFIG_RFID_SL2623) && GKT_CONFIG_RFID_SL2623	
	int key_masked;
	if (rfid_type == GKT_RFID_CHIP_TYPE_SL2623) {
		if (gp_window_unreset_data->rfid_standby_mode == GKT_RFID_STANBY_SOFT_POWEROFF) {/*standby poweroff mode*/
			gkt_rfid_control(GKT_RFID_CTRL_DISABLE, GKT_RFID_EXT_DATA_NONE);	
			gkt_rfid_standby_soft_poweroff();
			gkt_rfid_standby_output_change_to_input();
		}	
		else {/*standby lpcd mode*/
			key_masked = gkt_event_is_masked(GKT_EVENT_KEY);
			if (!key_masked)
				gkt_event_mask_single(GKT_EVENT_KEY, GKT_KEY_MASK_F_LED_DETACH);
			
			gkt_rfid_control(GKT_RFID_CTRL_DISABLE, GKT_RFID_EXT_DATA_NONE);
			retval = gkt_rfid_calibrate(1, GKT_RFID_CALIBRATE_STANDBY);
			if (retval != GKT_SUCCESS) 
				gkt_rfid_standby_soft_poweroff();
			else {
				if (amount.used_nums != 0) {
					amount.used_nums = 0;
					gkt_user_get_amount(&amount, GKT_USER_AUTH_MAX, GKT_USER_TYPE_CARD);
					if (amount.used_nums == 0) {
						gkt_rfid_control(GKT_RFID_CTRL_DISABLE, GKT_RFID_EXT_DATA_NONE);
						gkt_rfid_standby_soft_poweroff();
					}
					else
						gkt_rfid_control(GKT_RFID_CTRL_ENABLE, GKT_RFID_EXT_DATA_NONE);
				}
				else 
					gkt_rfid_control(GKT_RFID_CTRL_ENABLE, GKT_RFID_EXT_DATA_NONE);
			}
			gkt_rfid_standby_output_change_to_input();
			
			if (!key_masked) {
				gkt_thread_sleep(100);
				gkt_event_unmask_single(GKT_EVENT_KEY);
			}
		}
	}
#endif
#if defined(GKT_CONFIG_RFID_YC5018) && GKT_CONFIG_RFID_YC5018
	if (rfid_type == GKT_RFID_CHIP_TYPE_YC5018) {
		if (gp_window_unreset_data->rfid_standby_mode == GKT_RFID_STANBY_SOFT_POWEROFF) {/*standby poweroff mode*/
			gkt_rfid_standby_soft_poweroff();
		}
		else {
			gkt_rfid_control(GKT_RFID_CTRL_DISABLE, GKT_RFID_EXT_DATA_NONE);
			
			retval = gkt_rfid_calibrate(1, GKT_RFID_CALIBRATE_STANDBY);
			if (retval != GKT_SUCCESS) 
				gkt_rfid_standby_soft_poweroff();
			else {
				if (amount.used_nums != 0) {
					amount.used_nums = 0;
					gkt_user_get_amount(&amount, GKT_USER_AUTH_MAX, GKT_USER_TYPE_CARD);
					if (amount.used_nums == 0)
						gkt_rfid_standby_soft_poweroff();
				}
			}
		}
		gkt_rfid_standby_output_change_to_input(); 
	} 
#endif	
#endif/*GKT_CONFIG_RFID_ENABLE*/

#if defined(GKT_CONFIG_FPS_ENABLE) && GKT_CONFIG_FPS_ENABLE
	gkt_fpsensor_control(GKT_FPS_CTRL_DISABLE,0);
	gkt_fpsensor_detect();
	gkt_fpsensor_lp_low_power(0,0);
#endif	
	window_data_save();
#if defined(GKT_CONFIG_SLIDING_CLOSURE_MAGNET_LEVEL)
	gkt_sliding_closure_magnet_degauss_sync();
#endif	
}

